package com.topisv.tms.service.work;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.hibernate.ejb.criteria.predicate.ComparisonPredicate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.google.common.base.Preconditions;
import com.taobao.api.response.WlbWaybillICancelResponse;
import com.topisv.tms.entity.AreaGroup;
import com.topisv.tms.entity.CusStockMerge;
import com.topisv.tms.entity.Customers;
import com.topisv.tms.entity.EdiGoodsSku;
import com.topisv.tms.entity.EdiOrder;
import com.topisv.tms.entity.EdiOrderItem;
import com.topisv.tms.entity.LogisticsCompany;
import com.topisv.tms.entity.LogisticsMailNo;
import com.topisv.tms.entity.OrderBackTask;
import com.topisv.tms.entity.QueryParamHolder;
import com.topisv.tms.entity.ShopSource;
import com.topisv.tms.entity.User;
import com.topisv.tms.entity.WorkGuaranteeTask;
import com.topisv.tms.entity.interfacetask.InterfaceTask;
import com.topisv.tms.entity.interfacetask.InterfaceTaskEnum;
import com.topisv.tms.entity.log.OrderLog;
import com.topisv.tms.entity.stock.CusStock;
import com.topisv.tms.entity.work.WorkBatch;
import com.topisv.tms.entity.work.WorkLog;
import com.topisv.tms.entity.work.WorkOrder;
import com.topisv.tms.entity.work.WorkOrderNoCascade;
import com.topisv.tms.entity.work.WorkTask;
import com.topisv.tms.entity.work.ExceptionOrder.ExceptionOrder;
import com.topisv.tms.repository.AreaGroupDao;
import com.topisv.tms.repository.CusStockMergeDao;
import com.topisv.tms.repository.CustomersDao;
import com.topisv.tms.repository.EdiGoodsSkuDao;
import com.topisv.tms.repository.EdiOrderDao;
import com.topisv.tms.repository.EdiOrderItemDao;
import com.topisv.tms.repository.ExpressConfigureDao;
import com.topisv.tms.repository.LogisticsCompanyDao;
import com.topisv.tms.repository.LogisticsMailNoDao;
import com.topisv.tms.repository.ShopSourceDao;
import com.topisv.tms.repository.UserDao;
import com.topisv.tms.repository.WorkGuaranteeTaskDao;
import com.topisv.tms.repository.log.OrderLogDao;
import com.topisv.tms.repository.stock.CusStockDao;
import com.topisv.tms.repository.task.MdSendOutTaskDao;
import com.topisv.tms.repository.work.WorkBatchDao;
import com.topisv.tms.repository.work.WorkLogDao;
import com.topisv.tms.repository.work.WorkOrderDao;
import com.topisv.tms.repository.work.WorkOrderNoCascadeDao;
import com.topisv.tms.repository.work.WorkTaskDao;
import com.topisv.tms.repository.work.ExceptionOrder.ExceptionOrderDao;
import com.topisv.tms.rest.qimen.qmsend.QmRequestSender;
import com.topisv.tms.rest.qimen.qmservice.DeliveryOrderConfirmService;
import com.topisv.tms.rest.qimen.qmservice.DeliveryProcessService;
import com.topisv.tms.service.EdiOrderService;
import com.topisv.tms.service.account.ShiroDbRealm.ShiroUser;
import com.topisv.tms.service.base.BaseService;
import com.topisv.tms.service.interfacetask.InterfaceTaskService;
import com.topisv.tms.service.prioritySend.OrderBackTaskService;
import com.topisv.tms.service.vo.WorkOrderInfoItemVo;
import com.topisv.tms.service.vo.WorkOrderInfoVo;
import com.topisv.tms.service.vo.deppon.common.DOPConstans;
import com.topisv.tms.utils.DateUtils;
import com.topisv.tms.utils.WmsContants;
import com.topisv.tms.utils.enums.StatusEnums;
// import com.topisv.tms.utils.http.SynchroShippedBatchQueue;
import com.topisv.tms.utils.taobao.TopClientUtils;

/**
 * 作业订单_service
 * 
 * @author ch
 * 
 */
@Component
@Transactional(readOnly = true)
public class WorkOrderService extends BaseService{

	private static final Logger log = LoggerFactory.getLogger(WorkOrderService.class);
	
	@Autowired
	private JdbcTemplate jdbcTemplate;
	
	@Autowired
	private WorkOrderDao workOrderDao;
	@Autowired
	private WorkOrderNoCascadeDao workOrderNoCascadeDao;
	@Autowired
	private EdiOrderItemDao ediOrderItemDao;
	@Autowired
	private WorkTaskDao workTaskDao;
	@Autowired
	private WorkBatchDao workBatchDao;
	@Autowired
	private UserDao userDao;
	@Autowired
	private OrderLogDao orderLogDao;
	@Autowired
	private WorkLogDao workLogDao;
	@Autowired
	private EdiOrderService ediOrderService;
	@Autowired
	private WorkBatchService workBatchService;
	@Autowired
	private ExceptionOrderDao exceptionOrderDao;
	@Autowired
	private CustomersDao customersDao;
	@Autowired
	private CusStockMergeDao cusStockMergeDao;
	@Autowired
	private CusStockDao cusStockDao;
	@Autowired
	private AreaGroupDao areaGroupDao;
	@Autowired
	private LogisticsMailNoDao logisticsMailNoDao;
	@Autowired
	private EdiGoodsSkuDao ediGoodsSkuDao;
	@Autowired
	private LogisticsCompanyDao logisticsCompanyDao;
	@Autowired
	private ShopSourceDao shopSourceDao;
	@Autowired
	private MdSendOutTaskDao mdSendOutTaskDao;	
	@Autowired
	private EdiOrderDao ediOrderDao;
	@Autowired
	private ExpressConfigureDao expressConfigureDao;
	
	
	@Resource(type=DeliveryProcessService.class)
	private QmRequestSender<Map<String,Object>> deliveryProcessService;
	
	@Resource(type=DeliveryOrderConfirmService.class)
	private QmRequestSender<String> deliveryOrderConfirmService;
	
	@Autowired
	private WorkGuaranteeTaskDao workGuaranteeTaskDao;
   @Autowired
    private InterfaceTaskService interfaceTaskService;
   
   @Autowired
	private OrderBackTaskService ttkdexOrderBackTaskService;
   
	public WorkOrder loadOrder(String batchCode, String ordeno){
		return workOrderDao.loadOrder(batchCode, ordeno);
	}
	
	public List<WorkOrder> findByTaskCode(String taskCode){
		return workOrderDao.findByTaskCode(taskCode);
	}
	
	public List<WorkOrder> findByGuaranteeCode(String guaranteeCode,String batchCode){
		return workOrderDao.findByGuaranteeTaskCode(guaranteeCode,batchCode);
	}

	/**
	 * 查找订单
	 * @param searchParams 查询参数
	 * @return
	 */
	public List<WorkOrder> loadOrder(Map<String, Object> searchParams) {
		if (searchParams.isEmpty()) {
			throw new IllegalArgumentException("searchParams can't be empty");
		}
		Specification<WorkOrder> spec = getWhereClause(searchParams);
		Sort sort = new Sort(Direction.ASC, "rankno");
		List<WorkOrder> orderList = this.workOrderDao.findAll(spec,sort);
		for (WorkOrder o: orderList){
			this.setDetail(o);
		}
		return orderList;
	}
	
	public long loadOrderCount(Map<String, Object> searchParams){
		Preconditions.checkArgument(!searchParams.isEmpty(),"searchParams can't be empty");
		Specification<WorkOrderNoCascade> spec = getWhereClauseNoCascade(searchParams);
		return workOrderNoCascadeDao.count(spec);
	}
	
	/**
	 * 查找订单
	 * @param searchParams 查询参数
	 * @return
	 */
	public List<WorkOrderNoCascade> loadOrderPage(Map<String, Object> searchParams,int pageNumber,int pageSize) {
		if (searchParams.isEmpty()) {
			throw new IllegalArgumentException("searchParams can't be empty");
		}
		Specification<WorkOrderNoCascade> spec = getWhereClauseNoCascade(searchParams);
		PageRequest pageRequest = buildPageRequest(pageNumber, pageSize, "id_asc");
		List<WorkOrderNoCascade> orderList = this.workOrderNoCascadeDao.findAll(spec,pageRequest).getContent();
		//订单详情
		HashMap<String,HashMap<String,Object>> cacheMap = new HashMap<String,HashMap<String,Object>>(); 
		cacheMap.put("customer", new HashMap<String,Object>());
		cacheMap.put("areagroup", new HashMap<String,Object>());
		cacheMap.put("expressCompany", new HashMap<String,Object>());
		if(orderList==null||orderList.size()==0){
			return orderList;
		}
		//使用缓存设置warehouse customer 等信息数据
		for (WorkOrderNoCascade o: orderList){
			this.setDetailCache(o);
		}
		//循环查出的单号
		List<String> orderNoList = new ArrayList<String>();
		for(WorkOrderNoCascade n:orderList){
			orderNoList.add(n.getOrderno());
		}
		//查询edi_order
		List<EdiOrder> eoList = this.ediOrderDao.findByOrdeno(orderNoList);
		//查询edi_order_item
		List<EdiOrderItem> orderItems = this.ediOrderItemDao.findByOrderno(orderNoList);
		//将edi_order_item和edi_order设置到work_order中
		for (WorkOrderNoCascade workOrder : orderList) {
			boolean findFlg = false;
			for (EdiOrder eo : eoList) {
				if (eo.getOrdeno().equals(workOrder.getOrderno())) {
					List<EdiOrderItem> eoi = new ArrayList<EdiOrderItem>();
					for (EdiOrderItem oi : orderItems) {
						if (oi.getOrdeno().equals(eo.getOrdeno())) {
							eoi.add(oi);
						}
					}
					eo.setOrderItems(eoi);
					workOrder.setOrder(eo);
					workOrder.setShopna(StringUtils.isBlank(eo.getShopna()) ? "" : eo.getShopna());//添加店铺名称 bug611 add LiBin 20161116
					findFlg = true;
					break;
				}
			}
			if (!findFlg) {
				EdiOrder neo = new EdiOrder();
				List<EdiOrderItem> eoi = new ArrayList<EdiOrderItem>();
				neo.setOrderItems(eoi);
				workOrder.setOrder(neo);
			}
		}
		fillOrderSysWeight(orderList);
		return orderList;
	}
	
	private void fillOrderSysWeight(List<WorkOrderNoCascade> orderList) {
		Map<String, EdiGoodsSku> goodsCache = new HashMap<String, EdiGoodsSku>();
		for (WorkOrderNoCascade workOrderNoCascade : orderList) {
			EdiOrder order = workOrderNoCascade.getOrder();
			List<EdiOrderItem> orderItems = order.getOrderItems();
			if (orderItems != null) {
				Integer totalWeight = 0;
				for (EdiOrderItem ediOrderItem : orderItems) {
					String customerCode = ediOrderItem.getCustomerCode();
					String sku = ediOrderItem.getSku();
					if (customerCode != null && sku != null) {
						String key = new StringBuilder().append(customerCode).append("_").append(sku).toString();
						boolean exists = goodsCache.containsKey(key);
						if (!exists) {
							EdiGoodsSku ediGoodsSku = ediGoodsSkuDao.findByCustomerCodeAndSku(customerCode, sku);
							goodsCache.put(key, ediGoodsSku);
						}
						EdiGoodsSku ediGoodsSku = goodsCache.get(key);
						if (ediGoodsSku != null) {
							Integer weight = ediGoodsSku.getWeight() == null ? 0 : ediGoodsSku.getWeight();
							Integer weightPkg = ediGoodsSku.getWeightPkg() == null ? 0 : ediGoodsSku.getWeightPkg();
							totalWeight += weight + weightPkg;
						}
					}
				}
				workOrderNoCascade.setSysWeight(totalWeight);
			}
		}
	}
	
	/**
	 * 查询条件封装
	 * @param searchParams
	 * @return
	 */
	private Specification<WorkOrder> getWhereClause(final Map<String, Object> searchParams) {
		
		return new Specification<WorkOrder>(){
			
		    @Override
		    public Predicate toPredicate(Root<WorkOrder> r, CriteriaQuery<?> q, CriteriaBuilder cb) {
		      Predicate pre = cb.conjunction();
		      
		      String customerCode=(String) searchParams.get("customerCode");
		      if(StringUtils.isNotBlank(customerCode)){
					pre.getExpressions().add(cb.equal(r.get("customerCode"),customerCode.trim()));
			  }
		      
		      String guaranteeCode=(String) searchParams.get("guaranteeCode");
		      if(StringUtils.isNotBlank(guaranteeCode)){
					pre.getExpressions().add(cb.equal(r.get("guaranteeCode"),guaranteeCode.trim()));
			  }
		      
		      String warehouseCode=(String) searchParams.get("warehouseCode");
		      if(StringUtils.isNotBlank(warehouseCode)){
					pre.getExpressions().add(cb.equal(r.get("warehouseCode"),warehouseCode.trim()));
			  }

		      String customerCodes=(String) searchParams.get("customerCodes");
		      if(StringUtils.isNotBlank(customerCodes)) {
		    	  String[] customerCodeSplit = customerCodes.split(":");
				  ComparisonPredicate[] tempCustomerCode = new ComparisonPredicate[customerCodeSplit.length];
				  int i = 0;
				  for (String _customerCode : customerCodeSplit) {
					 tempCustomerCode[i] = (ComparisonPredicate) cb.equal(r.get("customerCode"), _customerCode);
					 i++;
				  }
				  pre.getExpressions().add(cb.or(tempCustomerCode));
		      }
		      String areagroups=(String) searchParams.get("areagroups");
		      if(StringUtils.isNotBlank(areagroups)) {
		    	  String[] areagroupSplit = areagroups.split(":");
				  ComparisonPredicate[] areagroupArray = new ComparisonPredicate[areagroupSplit.length];
				  int j = 0;
				  for (String _areagroup : areagroupSplit) {
						areagroupArray[j] = (ComparisonPredicate) cb.equal(r.get("warehouseCode"), _areagroup);
						j++;
				  }
				  pre.getExpressions().add(cb.or(areagroupArray));
			  }
		      String batchCode=(String) searchParams.get("batchCode");
		      if(StringUtils.isNotBlank(batchCode)){
					pre.getExpressions().add(cb.equal(r.get("batchCode"),batchCode.trim()));
			  }	
		      
		      String taskCode=(String) searchParams.get("taskCode");
		      if(StringUtils.isNotBlank(taskCode)){
					pre.getExpressions().add(cb.equal(r.get("taskCode"),taskCode.trim()));
			  }	
		      
		      //订单号
		      String orderno=(String) searchParams.get("orderno");
		      if(StringUtils.isNotBlank(orderno)){
					pre.getExpressions().add(
							cb.or(
									cb.equal(r.<EdiOrder>get("order").get("ordeno"),orderno.trim()),
									cb.equal(r.<EdiOrder>get("order").get("fromno"),orderno.trim()),
									cb.equal(r.<EdiOrder>get("order").get("customerOrdeno"),orderno.trim())
								)
					);
			  }	
		      
		      //订单号或者快递单号
		      String ordernoOrExpressno=(String) searchParams.get("ordernoOrExpressno");
		      if(StringUtils.isNotBlank(ordernoOrExpressno)){
					pre.getExpressions().add(
							cb.or(
									cb.equal(r.<EdiOrder>get("order").get("ordeno"),ordernoOrExpressno.trim()),
									cb.equal(r.<EdiOrder>get("order").get("fromno"),ordernoOrExpressno.trim()),
									cb.equal(r.<EdiOrder>get("order").get("customerOrdeno"),ordernoOrExpressno.trim()),
									cb.equal(r.get("ebillNo"),ordernoOrExpressno.trim()),
									cb.equal(r.get("expressNo"),ordernoOrExpressno.trim())
								)
					);
			  }	
		      
		      String expressNo=(String) searchParams.get("expressNo");
		      if(StringUtils.isNotBlank(expressNo)){
					pre.getExpressions().add(
							cb.or(
									cb.equal(r.get("expressNo"),expressNo.trim()),
									cb.equal(r.get("ebillNo"),expressNo.trim())
								)
				 );
			  }	
		      
		      String ebillNo=(String) searchParams.get("ebillNo");
		      if(StringUtils.isNotBlank(ebillNo)){
					pre.getExpressions().add(
							cb.or(
									cb.equal(r.get("expressNo"),expressNo.trim()),
									cb.equal(r.get("ebillNo"),expressNo.trim())
								)
					);
			  }	
		      
		      String status=(String) searchParams.get("status");
		      if(StringUtils.isNotBlank(status)){
		    	  if(status.equals("countStock")){
		    		  pre.getExpressions().add(
		    				  cb.or(
		    						  cb.equal(r.get("status"),"3"),
		    						  cb.equal(r.get("status"),"4"),
		    						  cb.equal(r.get("status"),"5"),
		    						  cb.equal(r.get("status"),"6"),
		    						  cb.equal(r.get("status"),"7"),
		    						  cb.equal(r.get("status"),"8"),
		    						  cb.equal(r.get("status"),"9")
		    					));
		    				  
		    	  }else if(status.equals("working")){ //作业中的订单
		    		  
		    		  //订单状态 (1.创建批次 2.创建任务 3.已拣货 4.已灯光拣选 9.待包装 5.已包装 6.已发货 )
		    		  pre.getExpressions().add(
		    				  cb.or(
		    						  cb.equal(r.get("status"),"1"),
		    						  cb.equal(r.get("status"),"2"),
		    						  cb.equal(r.get("status"),"3"),
		    						  cb.equal(r.get("status"),"4"),
		    						  cb.equal(r.get("status"),"5"),
		    						  cb.equal(r.get("status"),"9")
		    					));
		    		  
		    	  }else{
		    		  pre.getExpressions().add(cb.equal(r.get("status"),status));  
		    	  }
			  }	
		      
		      String cancelStatus=(String) searchParams.get("cancelStatus");
		      if(StringUtils.isNotBlank(cancelStatus)){
		    	  if("exception".equals(cancelStatus)){
		    		  pre.getExpressions().add(cb.notEqual(r.get("cancelStatus"),"ok"));
		    	  }else{
		    		  pre.getExpressions().add(cb.equal(r.get("cancelStatus"),cancelStatus));
		    	  }
		    		  
			  }	
		      
		      
		      Date fromDate= (Date) searchParams.get("fromDate");
		      if (fromDate != null) {
		        pre.getExpressions().add(cb.greaterThanOrEqualTo(r.<Date>get("createTime"), fromDate));
		      }
		      
		      Date toDate= (Date) searchParams.get("toDate");
		      if (toDate != null) {
		        pre.getExpressions().add(cb.lessThanOrEqualTo(r.<Date>get("createTime"), toDate));
		      }
		      
		      String sku=(String) searchParams.get("sku");
		      if(StringUtils.isNotBlank(sku)){
					pre.getExpressions().add(cb.like(r.<String>get("goodsInfo"),"%"+sku+"%"));
			  }	
		      String sendOutStatus=(String) searchParams.get("sendOutStatus");
		      if(StringUtils.isNotBlank(sendOutStatus)){
		    	  pre.getExpressions().add(cb.equal(r.<String>get("sendOutStatus"),sendOutStatus));
		      }
		      
		      Date inputFromDate= (Date) searchParams.get("inputFromDate");//导入时间
              if (inputFromDate != null) {
                  pre.getExpressions().add(cb.greaterThanOrEqualTo(r.<Date>get("inputTime"), inputFromDate));
              }
              
              Date inputToDate= (Date) searchParams.get("inputToDate");
              if (inputToDate != null) {
                  pre.getExpressions().add(cb.lessThanOrEqualTo(r.<Date>get("inputTime"), inputToDate));
              }
		      
              String expressBuiltType=(String) searchParams.get("expressBuiltType");//快递单产生的方式
              if(StringUtils.isNotBlank(expressBuiltType)){
                  pre.getExpressions().add(cb.equal(r.get("expressBuiltType"),expressBuiltType));
              } 
              
              //添加快递公司条件
		      String cacode = (String) searchParams.get("companyCode");
		      if(StringUtils.isNotBlank(cacode)){
		          pre.getExpressions().add(cb.equal(r.<String>get("expressCompany"), cacode));
		      }
		      
		      //添加订单状态条件
		      String workStatus = (String) searchParams.get("workStatus");
		      if(StringUtils.isNotBlank(workStatus)){
		          pre.getExpressions().add(cb.equal(r.<String>get("status"), workStatus));
		      }
              
		      return pre;
		    }
		  };
       }
	
	
	/**
	 * 查询条件封装
	 * @param searchParams
	 * @return
	 */
	private Specification<WorkOrderNoCascade> getWhereClauseNoCascade(final Map<String, Object> searchParams) {
		
		return new Specification<WorkOrderNoCascade>(){
			
		    @Override
		    public Predicate toPredicate(Root<WorkOrderNoCascade> r, CriteriaQuery<?> q, CriteriaBuilder cb) {
		      Predicate pre = cb.conjunction();
		      
		      String customerCode=(String) searchParams.get("customerCode");
		      if(StringUtils.isNotBlank(customerCode)){
					pre.getExpressions().add(cb.equal(r.get("customerCode"),customerCode.trim()));
			  }
		      
		      String guaranteeCode=(String) searchParams.get("guaranteeCode");
		      if(StringUtils.isNotBlank(guaranteeCode)){
					pre.getExpressions().add(cb.equal(r.get("guaranteeCode"),guaranteeCode.trim()));
			  }
		      
		      String warehouseCode=(String) searchParams.get("warehouseCode");
		      if(StringUtils.isNotBlank(warehouseCode)){
					pre.getExpressions().add(cb.equal(r.get("warehouseCode"),warehouseCode.trim()));
			  }

		      String customerCodes=(String) searchParams.get("customerCodes");
		      if(StringUtils.isNotBlank(customerCodes)) {
		    	  String[] customerCodeSplit = customerCodes.split(":");
				  ComparisonPredicate[] tempCustomerCode = new ComparisonPredicate[customerCodeSplit.length];
				  int i = 0;
				  for (String _customerCode : customerCodeSplit) {
					 tempCustomerCode[i] = (ComparisonPredicate) cb.equal(r.get("customerCode"), _customerCode);
					 i++;
				  }
				  pre.getExpressions().add(cb.or(tempCustomerCode));
		      }
		      String areagroups=(String) searchParams.get("areagroups");
		      if(StringUtils.isNotBlank(areagroups)) {
		    	  String[] areagroupSplit = areagroups.split(":");
				  ComparisonPredicate[] areagroupArray = new ComparisonPredicate[areagroupSplit.length];
				  int j = 0;
				  for (String _areagroup : areagroupSplit) {
						areagroupArray[j] = (ComparisonPredicate) cb.equal(r.get("warehouseCode"), _areagroup);
						j++;
				  }
				  pre.getExpressions().add(cb.or(areagroupArray));
			  }
		      String batchCode=(String) searchParams.get("batchCode");
		      if(StringUtils.isNotBlank(batchCode)){
					pre.getExpressions().add(cb.equal(r.get("batchCode"),batchCode.trim()));
			  }	
		      
		      String taskCode=(String) searchParams.get("taskCode");
		      if(StringUtils.isNotBlank(taskCode)){
					pre.getExpressions().add(cb.equal(r.get("taskCode"),taskCode.trim()));
			  }	
		      
		      String expressCompany=(String) searchParams.get("expressCompany");
		      if(StringUtils.isNotBlank(expressCompany)){
					pre.getExpressions().add(cb.equal(r.get("expressCompany"),expressCompany));
			  }	
		      
		      //订单号
		      String orderno=(String) searchParams.get("orderno");
		      if(StringUtils.isNotBlank(orderno)){
					pre.getExpressions().add(
							cb.or(
									cb.equal(r.<EdiOrder>get("order").get("ordeno"),orderno.trim()),
									cb.equal(r.<EdiOrder>get("order").get("fromno"),orderno.trim()),
									cb.equal(r.<EdiOrder>get("order").get("customerOrdeno"),orderno.trim())
								)
					);
			  }	
		      
		      //订单号或者快递单号
		      String ordernoOrExpressno=(String) searchParams.get("ordernoOrExpressno");
		      if(StringUtils.isNotBlank(ordernoOrExpressno)){
					pre.getExpressions().add(
							cb.or(
									cb.equal(r.<EdiOrder>get("order").get("ordeno"),ordernoOrExpressno.trim()),
									cb.equal(r.<EdiOrder>get("order").get("fromno"),ordernoOrExpressno.trim()),
									cb.equal(r.<EdiOrder>get("order").get("customerOrdeno"),ordernoOrExpressno.trim()),
									cb.equal(r.get("ebillNo"),ordernoOrExpressno.trim()),
									cb.equal(r.get("expressNo"),ordernoOrExpressno.trim())
								)
					);
			  }	
		      
		      String expressNo=(String) searchParams.get("expressNo");
		      if(StringUtils.isNotBlank(expressNo)){
					pre.getExpressions().add(
							cb.or(
									cb.equal(r.get("expressNo"),expressNo.trim()),
									cb.equal(r.get("ebillNo"),expressNo.trim())
								)
				 );
			  }	
		      
		      String ebillNo=(String) searchParams.get("ebillNo");
		      if(StringUtils.isNotBlank(ebillNo)){
					pre.getExpressions().add(
							cb.or(
									cb.equal(r.get("expressNo"),expressNo.trim()),
									cb.equal(r.get("ebillNo"),expressNo.trim())
								)
					);
			  }	
		      
		      String status=(String) searchParams.get("status");
		      if(StringUtils.isNotBlank(status)){
		    	  if(status.equals("countStock")){
		    		  pre.getExpressions().add(
		    				  cb.or(
		    						  cb.equal(r.get("status"),"3"),
		    						  cb.equal(r.get("status"),"4"),
		    						  cb.equal(r.get("status"),"5"),
		    						  cb.equal(r.get("status"),"6"),
		    						  cb.equal(r.get("status"),"7"),
		    						  cb.equal(r.get("status"),"8"),
		    						  cb.equal(r.get("status"),"9")
		    					));
		    				  
		    	  }else if(status.equals("working")){ //作业中的订单
		    		  
		    		  //订单状态 (1.创建批次 2.创建任务 3.已拣货 4.已灯光拣选 9.待包装 5.已包装 6.已发货 )
		    		  pre.getExpressions().add(
		    				  cb.or(
		    						  cb.equal(r.get("status"),"1"),
		    						  cb.equal(r.get("status"),"2"),
		    						  cb.equal(r.get("status"),"3"),
		    						  cb.equal(r.get("status"),"4"),
		    						  cb.equal(r.get("status"),"5"),
		    						  cb.equal(r.get("status"),"9")
		    					));
		    		  
		    	  }else{
		    		  pre.getExpressions().add(cb.equal(r.get("status"),status));  
		    	  }
			  }	
		      
		      String cancelStatus=(String) searchParams.get("cancelStatus");
		      if(StringUtils.isNotBlank(cancelStatus)){
		    	  if("exception".equals(cancelStatus)){
		    		  pre.getExpressions().add(cb.notEqual(r.get("cancelStatus"),"ok"));
		    	  }else{
		    		  pre.getExpressions().add(cb.equal(r.get("cancelStatus"),cancelStatus));
		    	  }
		    		  
			  }	
		      
		      
		      Date fromDate= (Date) searchParams.get("fromDate");
		      if (fromDate != null) {
		        pre.getExpressions().add(cb.greaterThanOrEqualTo(r.<Date>get("finishTime"), fromDate));
		      }
		      
		      Date toDate= (Date) searchParams.get("toDate");
		      if (toDate != null) {
		        pre.getExpressions().add(cb.lessThanOrEqualTo(r.<Date>get("finishTime"), toDate));
		      }
		      
		      String sku=(String) searchParams.get("sku");
		      if(StringUtils.isNotBlank(sku)){
					pre.getExpressions().add(cb.like(r.<String>get("goodsInfo"),"%"+sku+"%"));
			  }	
		      String sendOutStatus=(String) searchParams.get("sendOutStatus");
		      if(StringUtils.isNotBlank(sendOutStatus)){
		    	  pre.getExpressions().add(cb.equal(r.<String>get("sendOutStatus"),sendOutStatus));
		      }	
		      
		      //添加快递公司条件
		      String cacode = (String) searchParams.get("companyCode");
		      if(StringUtils.isNotBlank(cacode)){
		          pre.getExpressions().add(cb.equal(r.<String>get("expressCompany"), cacode));
		      }
		      
		      //添加订单状态条件
		      String workStatus = (String) searchParams.get("workStatus");
		      if(StringUtils.isNotBlank(workStatus)){
		          pre.getExpressions().add(cb.equal(r.<String>get("status"), workStatus));
		      }
		      
		      
		      return pre;
		    }
		  };
       }

	/**
	 * 发货时校验发票状态
	 * @param order
	 * @return String
	 */
	public String checkInvoiceStatus(WorkOrder order){
		if (order != null && WmsContants.CUSTOMER_MID.equals(order.getCustomerCode())) {
			if("1".equals(order.getNeedInvoice()) && StringUtils.isBlank(order.getInvoiceNo())){
				return "invoice";
			}
		}
		return null;
	}
	private void sendMessage2Deppon(WorkOrder order){
		if(StatusEnums.WAYBILL_TYPE_EBILL.getStatus().equals(order.getBillType()) && DOPConstans.LOGISTIC_PROVIDERID_DEFAULT.equals(order.getExpressCompany())){
//			SynchroShippedBatchQueue.putSendMessageQueue(new StringBuilder()
//			.append(JMSMessageType.CREATE_DEPPON_ORDER.getType())
//			.append(StatusEnums.split.getStatus())
//			.append(order.getOrder().getOrdeno()).toString());
		}
	}
	/**
	 * 发货_称重
	 * @param  expressNo 运单号
	 * @param  jobuuid 员工uuid
	 * @return noexist:不存在此订单      nostatus:不在发货状态     success:发货成功
	 */
	@Transactional(readOnly = false,rollbackFor=Exception.class)
	public String send(String expressNo,String jobuuid,Integer weight) throws Exception {
		try {
			WorkOrder order=this.loadByExpressNo(expressNo);
			if(order==null){
				return "noexist"; //不存在此订单
			}
			
			//取消单
			if("cancel".equals(order.getCancelStatus())){
				return "cancel";
			}else{
				ExceptionOrder exceptionOrder = exceptionOrderDao.loadByOrderno(order.getOrder().getOrdeno());
				if(exceptionOrder != null){
					//设置订单状态:取消
					order.getOrder().setOrderStatus("cancel");
					ediOrderService.save(order.getOrder());
					//设置作业单状态:取消
					order.setCancelStatus("cancel");
					workOrderDao.save(order);
					return "cancel";
				}
			}
			
			if("fail".equals(order.getSendOutStatus())){
				return "fail";
			}
			
			String status=order.getStatus();
			if(!"5".equals(status)){
				if("6".equals(status) || "7".equals(status)){
					return "sended"; //已发货
				}else{
					return "nostatus"; //不在发货状态
				}
			}
			
			//校验发票是否打印
			String msg = null;
			if((msg = checkInvoiceStatus(order)) != null){
				return msg;
			}
			String guaranteeStatus = order.getGuaranteeStatus();
			String guaranteeCode = order.getGuaranteeCode();
			if("".equals(guaranteeCode)||guaranteeCode !=null){
				if("".equals(guaranteeStatus)||guaranteeStatus==null){
					return "guaranteeStatus";
				}
			}
			
			User user=this.userDao.findByJobuuid(jobuuid);
			Date now=new Date();
			
			//修改订单状态
			order.setStatus("6"); //订单状态 (1.创建批次 2.创建任务 3.已拣货  4.已灯光拣选  9.待包装   5.已包装  6.已发货  7.已签收  8.异常 )
			order.setWeight(weight);//重量
			this.workOrderDao.save(order);
			
			//订单日志
			OrderLog orderlog=new OrderLog(order.getOrder().getOrdeno(),
					order.getOrder().getCustomerCode(), 
					"5", //操作类型 （1.创建批次 2.创建任务  3.拣货完成 4.包装完成 5.发货完成 6.签收完成 7.异常登记 8.完成灯光拣选任务 9.打印单据）
					user,
					now,
					null, 
					user.getRealname()+"执行发货(称重)操作");
			this.orderLogDao.save(orderlog);
			
			//修改美的订单确认任务表
			updateDoneNum(order);

			try{
				if("ebill".equals(order.getBillType())&&"STO".equals(order.getExpressCompany())){
//					ExpressConfigure ec = expressConfigureDao.findByWarehouseAndCompany(order.getWarehouseCode(), order.getExpressCompany());
//					MailSTOUtil.sendOrderInfo(order.getOrder(),ec);
				}else if("ebill".equals(order.getBillType())&&"HTKY".equals(order.getExpressCompany())){
				    /* begin remove 20160607 采用异步处理 by lianghe.yuan */
                    /**
                    ExpressConfigure ec = expressConfigureDao.findByWarehouseAndCompany(order.getWarehouseCode(), "HTKY");
                    WarehouseAddress wha = warehouseAddressService.findByWarehouseCode(order.getWarehouseCode());
                    MailBSHTUtil.deliveryRequestBack(order.getOrder(), ec,wha,order.getEbillNo());
                    */
                    /* end remove 20160607 采用异步处理 by lianghe.yuan */
				    
				    /* begin add 20160607 写接口任务表，job处理 by lianghe.yuan */
                    InterfaceTask task = new InterfaceTask();
                    task.setType(InterfaceTaskEnum.TYPE_MAIL_BS);
                    task.setRelatedNo(order.getOrder().getOrdeno());
                    task.setRelatedId(order.getOrder().getId());
                    task.setCreatedTime(new Date());
                    interfaceTaskService.saveTask(task);
                    /* end add 20160607 写接口任务表，job处理 by lianghe.yuan */
				}
			}catch (Exception e) {
				log.error("---------订单信息发送失败-----------");
			}
			
			/* begin add 20160607 写接口任务表，job处理 by lianghe.yuan */
             InterfaceTask task = new InterfaceTask();
             task.setType(InterfaceTaskEnum.TYPE_QM_DELIVERY_PROCESS);
             task.setRelatedNo(order.getOrder().getOrdeno());
             task.setRelatedId(order.getOrder().getId());
             task.setCreatedTime(new Date());
             interfaceTaskService.saveTask(task);
             /* end add 20160607 写接口任务表，job处理 by lianghe.yuan */
			
             /* begin add 20160607 写接口任务表，job处理 by lianghe.yuan */
              InterfaceTask task2 = new InterfaceTask();
              task2.setType(InterfaceTaskEnum.TYPE_QM_DELIVERY_ORDER_CONFIRM);
              task2.setRelatedNo(order.getOrder().getOrdeno());
              task2.setRelatedId(order.getOrder().getId());
              task2.setCreatedTime(new Date());
              interfaceTaskService.saveTask(task2);
              /* end add 20160607 写接口任务表，job处理 by lianghe.yuan */
              
              //如果是天天快递并是优先派送的要保存到天天订单回传任务表里 bug536  by zhangweize
              if ("TTKDEX".equals(order.getExpressCompany()) && "1".equals(order.getPrioritySendFlag())){
            	  OrderBackTask  ttkdexOrderBackTask= new OrderBackTask();
                  ttkdexOrderBackTask.setCustomerCode(order.getCustomerCode());
                  ttkdexOrderBackTask.setType("系统订单");
                  ttkdexOrderBackTask.setRelatedNo(order.getOrder().getOrdeno());
                  ttkdexOrderBackTask.setRelatedId(order.getId());
                  ttkdexOrderBackTask.setCreatedTime(new Date());
                  ttkdexOrderBackTaskService.saveTask(ttkdexOrderBackTask);
              }
              
			return "success";
		
		} catch (Exception e) {
			
			throw new Exception(e);
		}
	}
	
	/**
	 * 订单发货完成后，同时修改批次、任务表的状态
	 * @param order
	 */
	@Transactional(readOnly = false,rollbackFor=Exception.class)
	public void afterOrderSendOut(WorkOrder order){
		Date now = new Date();
//		SynchroShippedBatchQueue.putSendMessageQueue(new StringBuilder("kuaidi_sendout").append(StatusEnums.split.getStatus()).append(order.getOrder().getOrdeno()).append("_").append(order.getCustomerCode()).append("_").append(order.getOrder().getMailNo()).append("_").append(order.getExpressCompany()).toString());
		
		//查看同一任务的其他订单，是否都已处理，如果都处理了，修改任务状态为：已发货（8）
		finishWorkTask(order, now);
		
		//查看同一批次其他订单是否完成发货
		finishWorkBatch(order, now);
		
		//发货时，如果快递是德邦，推送消息到德邦平台
		sendMessage2Deppon(order);
		
		//添加发货完成时间
		order.setFinishTime(now);
		this.workOrderDao.save(order);
	}
	/**
	 *订单发货完成后，同时修改批次、任务表的状态
	 * @param expressNo
	 */
	@Transactional(readOnly = false,rollbackFor=Exception.class)
	public void afterOrderSendOut(String expressNo){
		WorkOrder workOrder = loadByExpressNo(expressNo);
		afterOrderSendOut(workOrder);
	}
	
	@Transactional(readOnly = false,rollbackFor=Exception.class)
	public void finishWorkBatch(WorkOrder order, Date now) {
		long unsendCount=this.workOrderDao.loadUnsendByBatchCode(order.getBatchCode());
		if (unsendCount == 0) {
			
			//任务状态
			WorkBatch batch=this.workBatchDao.loadbatchByBatchCode(order.getBatchCode());
			batch.setStatus("5");//批次状态 (1.已创建批次 2.已创建任务 3.已拣货  4.已包装  5.已发货)
		    this.workBatchDao.save(batch);
		    
		    //作业日志
		    WorkLog workLog=new WorkLog(
		    		batch.getBatchCode(),
		    		"10", //操作类型 (1.创建批次 2.创建任务 3.领取拣货任务  4.完成拣货任务 5.领取灯光拣选任务 6.完成灯光拣选任务  7.领取包装任务 8完成包装任务  9.领取发货任务  10.完成发货任务   )
		    		"完成全部发货",
		    		now,
		    		null);
		    this.workLogDao.save(workLog);
//		    SynchroShippedBatchQueue.putSendMessageQueue("createBatchWMS"+StatusEnums.split.getStatus()+batch.getBatchCode());
		}
	}
	@Transactional(readOnly = false,rollbackFor=Exception.class)
	public void finishWorkTask(WorkOrder order, Date now) {
		long unsendCount=this.workOrderDao.loadUnsendByBatchCode(order.getBatchCode());
		if (unsendCount == 0) {
			WorkTask task=this.workTaskDao.loadTaskByTaskCode(order.getTaskCode());
			task.setStatus("9");//任务状态( 1.创建任务 2.已分配拣货任务 3.已拣货 4. 已分配灯光拣选任务 5.已经灯光拣选 6.已分配包装任务 7.已包装 8.已分配发货任务 9.已发货 10.灯光拣选进行中.. 11.推车拣选进行中.. 12.拣货中...)
			task.setFinishTime(now);
			this.workTaskDao.save(task);
			
			WorkLog workLog=new WorkLog(
					task.getBatchCode(),
					"10", //操作类型 (1.创建批次 2.创建任务 3.完成拣货 4.完成包装 5.完成发货   )
					"完成发货任务（"+task.getTaskCode()+"）", 
					now, 
					null);
			this.workLogDao.save(workLog);
		}
	}
	
	public void updateDoneNum(WorkOrder order){
		mdSendOutTaskDao.updateDoneNum(order.getOrder().getCustomerOrdeno(), order.getGoodsNum());
	}
	
	@Transactional(readOnly = false,rollbackFor=Exception.class)
	public void updateSendStatusByOrder(String sendOutStatus,Long id){
		workOrderDao.updateSendStatusByOrder(sendOutStatus, id);
	}
	@Transactional(readOnly = false,rollbackFor=Exception.class)
	public void updateByBatchCode(String batch){
		workOrderDao.updateByBatchCode(batch);
	}
	
	/**
	 * 发货_不称重
	 * @param  expressNo 运单号
	 * @param  jobuuid 员工uuid
	 * @return noexist:不存在此订单      nostatus:不在发货状态     success:发货成功
	 */
	@Transactional(readOnly = false,rollbackFor=Exception.class)
	public String send_noweight(String expressNo,String jobuuid) throws Exception {
		return send_noweight(expressNo,jobuuid,false);
	}
	/**
	 * 
	 * @param  expressNo 运单号
	 * @param  jobuuid 员工uuid
	 * @param allowMutil  允许多件不称重
	 * @return noexist:不存在此订单      nostatus:不在发货状态     success:发货成功
	 * @throws Exception
	 */
	@Transactional(readOnly=false)
	public String send_noweight(String expressNo,String jobuuid,boolean allowMutil) throws Exception {
		try {
			WorkOrder order=this.loadByExpressNo(expressNo);
			
			//不存在此订单
			if(order==null){
				return "noexist"; 
			}
			
			String orderno=order.getOrder().getOrdeno();
			
			//取消单
			if("cancel".equals(order.getCancelStatus())){
				return "cancel";
			}else{
				ExceptionOrder exceptionOrder = exceptionOrderDao.loadByOrderno(order.getOrder().getOrdeno());
				if(exceptionOrder != null){
					//设置订单状态:取消
					order.getOrder().setOrderStatus("cancel");
					ediOrderService.save(order.getOrder());
					//设置作业单状态:取消
					order.setCancelStatus("cancel");
					workOrderDao.save(order);
					return "cancel";
				}
			}
			if("fail".equals(order.getSendOutStatus())){
				return "fail";
			}
			
			//不在发货状态
			String status=order.getStatus();
			if(!"5".equals(status)){
				if("6".equals(status) || "7".equals(status)){
					return "sended"; //已发货
				}else{
					return "nostatus"; //不在发货状态
				}
			}
			
			//多件必须称重发货
			int goodsNum=order.getGoodsNum();
			if(!allowMutil && goodsNum>1){
				return "multi"; 
			}
			
			//统计商品重量
			Integer weight_total=0;
			String goodsInfo=order.getGoodsInfo();
			String[] goodsInfoSplit=goodsInfo.split(";");
			
			for (String info : goodsInfoSplit) {
				String[] infoSplit=info.split(":");
				String sku=infoSplit[0];
				String strnum = infoSplit[1];
				int num =0;
				num = Integer.parseInt(strnum);
				EdiGoodsSku _ediGoodsSku=this.ediGoodsSkuDao.findByCustomerCodeAndSku(order.getCustomerCode(), sku);
				if(_ediGoodsSku==null){
					return "nosetting"; //无重量配置
				}
				Integer _weight=_ediGoodsSku.getWeight();
				Integer _weightPkg=_ediGoodsSku.getWeightPkg();
				
				if( _weight==null || _weightPkg==null){
					return  "nosetting"; //无重量配置
				}else{
					weight_total +=_weight*num+_weightPkg;
				}
			}
			
			//校验发票是否打印
			String msg = null;
			if((msg = checkInvoiceStatus(order)) != null){
				return msg;
			}
			String guaranteeStatus = order.getGuaranteeStatus();
			String guaranteeCode = order.getGuaranteeCode();
			if("".equals(guaranteeCode)||guaranteeCode !=null){
				if("".equals(guaranteeStatus)||guaranteeStatus==null){
					return "guaranteeStatus";
				}
			}
			User user=this.userDao.findByJobuuid(jobuuid);
			Date now=new Date();
			
			//修改订单状态
			order.setStatus("6"); //订单状态 (1.创建批次 2.创建任务 3.已拣货  4.已灯光拣选  9.待包装   5.已包装  6.已发货  7.已签收  8.异常 )
			order.setWeight(weight_total);//重量
			this.workOrderDao.save(order);
			
			//订单日志
			OrderLog orderlog=new OrderLog(orderno,
					order.getOrder().getCustomerCode(), 
					"5", //操作类型 （1.创建批次 2.创建任务  3.拣货完成 4.包装完成 5.发货完成 6.签收完成 7.异常登记 8.完成灯光拣选任务 9.打印单据）
					user,
					now,
					null, 
					user.getRealname()+"执行发货（不称重）操作");
			this.orderLogDao.save(orderlog);
			
			try{
				if("ebill".equals(order.getBillType())&&"STO".equals(order.getExpressCompany())){
//					ExpressConfigure ec = expressConfigureDao.findByWarehouseAndCompany(order.getWarehouseCode(), order.getExpressCompany());
//					MailSTOUtil.sendOrderInfo(order.getOrder(),ec);
				}else if("ebill".equals(order.getBillType())&&"HTKY".equals(order.getExpressCompany())){
                    InterfaceTask task = new InterfaceTask();
                    task.setType(InterfaceTaskEnum.TYPE_MAIL_BS);
                    task.setRelatedNo(order.getOrder().getOrdeno());
                    task.setRelatedId(order.getId());
                    task.setCreatedTime(new Date());
                    interfaceTaskService.saveTask(task);
				}
			}catch (Exception e) {
				log.error("---------订单信息发送失败-----------");
			}
			
             InterfaceTask task = new InterfaceTask();
             task.setType(InterfaceTaskEnum.TYPE_QM_DELIVERY_PROCESS);
             task.setRelatedNo(order.getOrder().getOrdeno());
             task.setRelatedId(order.getOrder().getId());
             task.setCreatedTime(new Date());
             interfaceTaskService.saveTask(task);
			
             
              InterfaceTask task2 = new InterfaceTask();
              task2.setType(InterfaceTaskEnum.TYPE_QM_DELIVERY_ORDER_CONFIRM);
              task2.setRelatedNo(order.getOrder().getOrdeno());
              task2.setRelatedId(order.getOrder().getId());
              task2.setCreatedTime(new Date());
              interfaceTaskService.saveTask(task2);
              
              //如果是天天快递并是优先派送的要保存到天天订单回传任务表里 bug536  by zhangweize
              if ("TTKDEX".equals(order.getExpressCompany()) && "1".equals(order.getPrioritySendFlag())){
            	  OrderBackTask  ttkdexOrderBackTask= new OrderBackTask();
                  ttkdexOrderBackTask.setCustomerCode(order.getCustomerCode());
                  ttkdexOrderBackTask.setType("系统订单");
                  ttkdexOrderBackTask.setRelatedNo(order.getOrder().getOrdeno());
                  ttkdexOrderBackTask.setRelatedId(order.getId());
                  ttkdexOrderBackTask.setCreatedTime(new Date());
                  ttkdexOrderBackTaskService.saveTask(ttkdexOrderBackTask);
              }
             
              
//			//淘宝订单全链路信息回传:已出库
//			try {
//				new TaoBaoAPITool().resendOrderStatus(orderno, "X_OUT_WAREHOUSE");
//			} catch (Exception e) {
//				
//			}
			//修改美的订单确认任务表
			updateDoneNum(order);
			
			return "success";
		} catch (Exception e) {
			
			throw new Exception(e);
		}
	}

	
	
	/**
	 * 查询订单
	 * @param id 订单ID
	 * @return
	 */
	public WorkOrder loadOrderById(Long id) {
      WorkOrder order=this.workOrderDao.findOne(id);
	  this.setDetail(order);
      return order;
	}
	
	public List<WorkOrderNoCascade> loadOrderNoCascadeByBatchCode(List<String> batchCodeList,Map<String,Customers> customerCacheMap) {
		if (batchCodeList == null || batchCodeList.isEmpty()) {
			return Collections.emptyList();
		}
		long start = System.currentTimeMillis();
		//查询workorder
		List<WorkOrderNoCascade> orderList=this.workOrderDao.loadOrderNoCascadeByBatchCode(batchCodeList);
		long endWorkOrder = System.currentTimeMillis();
		log.info("WorkOrderNoCascade查询:"+(endWorkOrder-start));
		List<String> orderNoList = new ArrayList<String>();
		for(WorkOrderNoCascade n:orderList){
			orderNoList.add(n.getOrderno());
		}
		//查询ediOrder
		List<EdiOrder> ediOrderListAll = this.ediOrderDao.findByOrdeno(orderNoList);
		long endEdiOrder = System.currentTimeMillis();
		log.info("EdiOrder查询:"+(endEdiOrder-endWorkOrder));
		//查询EdiOrderItem
		List<EdiOrderItem> orderItems = this.ediOrderItemDao.findByOrderno(orderNoList);
		long endEdiOrderItem = System.currentTimeMillis();
		log.info("EdiOrderItem查询:"+(endEdiOrderItem-endEdiOrder));
		for (WorkOrderNoCascade o: orderList){
			for(EdiOrder edio:ediOrderListAll){
				if(o.getOrderno().equals(edio.getOrdeno())){
					o.setOrder(edio);
					ediOrderListAll.remove(edio);
					break;
				}
			}
			String customerCode=o.getCustomerCode();
			if(customerCacheMap.containsKey(customerCode)){
				o.setCustomer(customerCacheMap.get(customerCode));
			}else {
				Customers customer=this.customersDao.findByCustomerCode(customerCode);
				o.setCustomer(customer);
				customerCacheMap.put(customerCode, customer);
			}
			
			List<EdiOrderItem> subOrderItems = new ArrayList<EdiOrderItem>();
			for(EdiOrderItem eoi:orderItems){
				if(eoi.getOrdeno().equals(o.getOrder().getOrdeno())){
					subOrderItems.add(eoi);
				}
			}
			o.getOrder().setOrderItems(subOrderItems);
//			this.setDetail(o);
		}
	    return orderList;
	}
	
	
	
	
	public List<WorkOrder> loadOrderByBatchCode(String batchCode) {
		List<WorkOrder> orderList=this.workOrderDao.loadOrderByBatchCode(batchCode);
		for (WorkOrder o: orderList){
			this.setDetail(o);
		}
	    return orderList;
	}
	
	public List<WorkOrder> loadOrderByBatchCode(List<String> batchCode) {
		List<WorkOrder> orderList=this.workOrderDao.loadOrderByBatchCode(batchCode);
		for (WorkOrder o: orderList){
			this.setDetail(o);
		}
	    return orderList;
	}
	
	/**
	 * 电子面单的修改状态
	 * @param orderno
	 * @param expressNo
	 * @param companyCode
	 */
	@Transactional(readOnly = false)
	public void setPrintStatus(String orderno,String expressNo,String companyCode) {
		
		ShiroUser user = (ShiroUser) SecurityUtils.getSubject().getPrincipal();
		User curUser=this.userDao.findOne(user.id);
		Date now=new Date();
		log.info("setPrintStatus:1--orderno="+orderno);
		//设置打印状态，写入快递单号
		WorkOrder workOrder=this.loadOrderByOrderno(orderno);
		//workOrder.setExpressNo(null);
		//workOrder.setBillType(StatusEnums.WAYBILL_TYPE_EBILL.getStatus());
		log.info("setPrintStatus:2--orderno="+orderno);
		String billType=StatusEnums.WAYBILL_TYPE_EBILL.getStatus();
		if(billType.equals("cbill")){ //普通运单
			//workOrder.setExpressNo(expressNo);
		}else if(billType.equals("ebill")){ //电子运单
			LogisticsMailNo logisticsMailNo=this.logisticsMailNoDao.findByMailNo(expressNo);
			if(logisticsMailNo!=null&&!"finish".equals(logisticsMailNo.getStatus())&&logisticsMailNo.getCompanyCode().equals(companyCode)){
				log.info("setPrintStatus:3--orderno="+orderno);
				logisticsMailNo.setStatus("finish");
				this.logisticsMailNoDao.save(logisticsMailNo);
			}
			//workOrder.setEbillNo(expressNo);
		}
		if(!"printed".equals(workOrder.getPrintStatus())){
			//workOrder.setPrintStatus("printed");
			
//			//淘宝订单全链路信息回传
//			try {
//				TaoBaoAPITool tbAPITool=new TaoBaoAPITool();
//				tbAPITool.resendOrderStatus(orderno, "X_SEND_PRINTED"); //已打发货单
//				tbAPITool.resendOrderStatus(orderno, "X_LOGISTICS_PRINTED"); //已打随箱单
//			} catch (Exception e) {
//				
//			}
			log.info("setPrintStatus:4--orderno="+orderno);
//			SynchroShippedBatchQueue.putSendMessageQueue("warehouseInfo"+StatusEnums.split.getStatus()
//					+orderno + "_dayin");
		}
		//workOrder.setExpressList(workOrder.getExpressList()==null? expressNo:(workOrder.getExpressList()+":"+expressNo));
		//workOrder.setExpressCompany(companyCode);
		//workOrder.setExpressNo(null);
		//workOrder.setBillType(StatusEnums.WAYBILL_TYPE_EBILL.getStatus());
		//this.workOrderDao.save(workOrder);
		log.info("setPrintStatus:5--orderno="+orderno);
		workOrderDao.updateForPrint("printed",workOrder.getExpressList()==null? expressNo:(workOrder.getExpressList()+":"+expressNo),
				companyCode,null,expressNo,StatusEnums.WAYBILL_TYPE_EBILL.getStatus(),workOrder.getId());
		//修改打印次数
		log.info("setPrintStatus:6--orderno="+orderno);
		workOrderDao.updatePrintFlag(workOrder.getPrintFlag()+1, workOrder.getId());
		//添加订单日志
		log.info("setPrintStatus:7--orderno="+orderno);
		OrderLog orderlog=new OrderLog(workOrder.getOrder().getOrdeno(),
				workOrder.getCustomerCode(), 
				"9", //操作类型 （1.创建拣货批次 2.创建拣货任务 3.修正拣货信息 4.拣货完成 5.包装完成 6.发货完成 7.签收完成 8.异常登记 9.已打印单据）
				curUser,
				now,
				null, 
				new StringBuilder().append(curUser.getRealname()).append("已打印快递单据:").append(expressNo).append("(").append(companyCode).append(")").toString());
		this.orderLogDao.save(orderlog);
		
		//查看同一作业的其他单，是否都已打印，如果是修改任务状态为： 已打印
		List<WorkOrder> unprintedList=this.workOrderDao.loadUnprintedList(workOrder.getTaskCode());
		if(unprintedList==null || unprintedList.size()==0){
		   log.info("setPrintStatus:8--orderno="+orderno);
		   WorkTask task=this.workTaskDao.loadTaskByTaskCode(workOrder.getTaskCode());
		   String printStatus = task.getPrintStatus();
		   if(!task.getPrintStatus().equals("printed")){
				Customers customers=this.customersDao.findByCustomerCode(workOrder.getCustomerCode());
                //判断是否打印随箱单或者保修单
				if("1".equals(customers.getPackStatus())){
					   //设置任务状态未已打印
					if("yes".equals(task.getPackformStatus())){
					      //task.setPrintStatus("printed");
						printStatus = "printed";
					   }
				}else{
					   printStatus = "printed";
				}
			   
			   
			   //作业日志
			   WorkLog workLog=new WorkLog(task.getBatchCode(),"11", "执行打印快递单据（"+task.getTaskCode()+"）", now, curUser);
			   this.workLogDao.save(workLog);
		   }
		   workTaskDao.updateExpressPrintStatus("yes", printStatus, task.getTaskCode());
		   //this.workTaskDao.save(task);
		}
	}
	
	/**
	 * 设置打印状态，写入快递单号
	 * @param ordeno
	 * @param expressNo 快递单号/电子运单号
	 */
	@Transactional(readOnly = false)
	public List<WorkOrder> setPrintStatus(String orderno,String expressNo,String companyCode,User curUser) {
		
		
		Date now=new Date();
		
		//设置打印状态，写入快递单号
		WorkOrder workOrder=this.loadOrderByOrderno(orderno);
		//workOrder.setEbillNo(null);
		//workOrder.setBillType(StatusEnums.WAYBILL_TYPE_CBILL.getStatus());
		//workOrder.setExpressNo(expressNo);
		//workOrder.setExpressList(workOrder.getExpressList()==null? expressNo:(workOrder.getExpressList()+":"+expressNo));
		//workOrder.setExpressCompany(companyCode);
		//this.workOrderDao.save(workOrder);
		workOrderDao.updateForPrint("printed",workOrder.getExpressList()==null? expressNo:(workOrder.getExpressList()+":"+expressNo),
				companyCode,expressNo,null,StatusEnums.WAYBILL_TYPE_CBILL.getStatus(),workOrder.getId());
		//添加订单日志
		OrderLog orderlog=new OrderLog(workOrder.getOrder().getOrdeno(),
				workOrder.getCustomerCode(), 
				"9", //操作类型 （1.创建拣货批次 2.创建拣货任务 3.修正拣货信息 4.拣货完成 5.包装完成 6.发货完成 7.签收完成 8.异常登记 9.已打印单据）
				curUser,
				now,
				null, 
				curUser.getRealname()+"已打印快递单据:"+expressNo);
		this.orderLogDao.save(orderlog);
		
		//查看同一作业的其他单，是否都已打印，如果是修改任务状态为： 已打印
		List<WorkOrder> unprintedList=this.workOrderDao.loadUnprintedList(workOrder.getTaskCode());
		if(unprintedList==null || unprintedList.size()==0){
		   WorkTask task=this.workTaskDao.loadTaskByTaskCode(workOrder.getTaskCode());
		   if(!"yes".equals(task.getExpressStatus())){
			   task.setExpressStatus("yes");
		   }
		   if(!task.getPrintStatus().equals("printed")){
				Customers customers=this.customersDao.findByCustomerCode(workOrder.getCustomerCode());
				if("1".equals(customers.getPackStatus())){
					   //设置任务状态未已打印
					if("1".equals(customers.getPackStatus())){
						 if("yes".equals(task.getPackformStatus())&&"yes".equals(task.getExpressStatus())){
						      task.setPrintStatus("printed");
						 }
					}else if("1".equals(customers.getPackStatus())){
						if("yes".equals(task.getPackformStatus())&&"yes".equals(task.getExpressStatus())){
							task.setPrintStatus("printed");
						}
					}else if((!"1".equals(customers.getPackStatus()))){
						if("yes".equals(task.getExpressStatus())){
							task.setPrintStatus("printed");
						}
					}
					
				}else{
					   //设置任务状态未已打印
					   if("yes".equals(task.getExpressStatus())){
					      task.setPrintStatus("printed");
					   }
				}
			   
			   
			   //作业日志
			   WorkLog workLog=new WorkLog(task.getBatchCode(),"11", "执行打印快递单据（"+task.getTaskCode()+"）", now, curUser);
			   this.workLogDao.save(workLog);
		   }
		   this.workTaskDao.save(task);
		}
		return unprintedList;
	}

	/**
	 * 查找订单
	 * @param ordeno
	 * @return
	 */
	public WorkOrder loadOrderByOrderno(String orderno) {
		WorkOrder workOrder= this.workOrderDao.loadByOrderno(orderno);
		if(workOrder!=null){
			List<EdiOrderItem> orderItems=this.ediOrderItemDao.findByOrdeno(workOrder.getOrder().getOrdeno());
			this.setGoodDetail(orderItems);
			workOrder.getOrder().setOrderItems(orderItems);
		}
		return workOrder;
	}
	/**
	 * 查找订单
	 * @param ordeno
	 * @return
	 */
	public WorkOrder loadOrderByOrdernoOnly(String orderno) {
		return workOrderDao.loadByOrderno(orderno);
	}
	


	/**
	 * 查询订单
	 * @param expressNo 快递单号
	 * @param orderno 订单号
	 * @return
	 */
	public WorkOrder loadByExpressNoAndOrderno(String expressNo, String orderno) {
		
		WorkOrder workOrder= this.workOrderDao.loadByExpressNoAndOrderno(expressNo,orderno);
		
		if(workOrder!=null){
			List<EdiOrderItem> orderItems = this.ediOrderItemDao.findByOrdeno(workOrder.getOrder().getOrdeno());
			workOrder.getOrder().setOrderItems(orderItems);
		}
		
		return workOrder;
	}
	
	/**
	 * 查找订单   add 20160708 取消单目前是运单号加了“_” by zhangweize
	 * @param expressNo 运单号
	 * @param expressNo_
	 * @return
	 */
	public WorkOrder loadWorkOrderByExpressNo(String expressNo,String expressNo_) {
		WorkOrder workOrder= this.workOrderDao.loadWorkOrderByExpressNo(expressNo,expressNo_);
		
		if(workOrder!=null){
			List<EdiOrderItem> orderItems = this.ediOrderItemDao.findByOrdeno(workOrder.getOrder().getOrdeno());
			this.setGoodDetail(orderItems);
			workOrder.getOrder().setOrderItems(orderItems);
		}
		return workOrder;
	}
	
	/**
	 * 查找订单
	 * @param expressNo 快递单号或者电子单号
	 * @return
	 */
	public WorkOrder loadByExpressNo(String expressNo) {
		WorkOrder workOrder= this.workOrderDao.loadByExpressNo1(expressNo);
		
		if(workOrder!=null){
			List<EdiOrderItem> orderItems = this.ediOrderItemDao.findByOrdeno(workOrder.getOrder().getOrdeno());
			this.setGoodDetail(orderItems);
			workOrder.getOrder().setOrderItems(orderItems);
		}
		return workOrder;
	}
	
	private void setGoodDetail(List<EdiOrderItem> orderItems){
		for(EdiOrderItem ediItem:orderItems){
			EdiGoodsSku goodSku=this.ediGoodsSkuDao.findByCustomerCodeAndSku(ediItem.getCustomerCode(),ediItem.getSku());
			ediItem.setEdiGoodsSku(goodSku);
		}
	}
	/**
	 * 查找订单
	 * @param expressNo 快递单号或者电子单号
	 * @return
	 */
	public WorkOrder loadByExpressNo2(String expressNo) {
		WorkOrder workOrder= this.workOrderDao.loadByExpressNo1(expressNo);
		return workOrder;
	}


	/**
	 * 查询待包装订单
	 * @param customerCode
	 * @return
	 */
	public List<WorkOrder> loadOrderForPkg(String warehouseCode,String flowType,String goodsInfo) {
		return this.workOrderDao.loadOrderForPkg(warehouseCode,flowType,goodsInfo);
	}

	/**
	 * 根据SKU查询待包装的订单
	 * @param customerCode 商家编码
	 * @param skuInfo sku信息
	 * @return
	 */
	public WorkOrder loadOrderBySku(String warehouseCode, String skuInfo) {
		
		//将skuInfo转化成map
		Map<String, Integer> skuMap=new HashMap<String, Integer>();
		String[] skuInfoSplit=skuInfo.split(";");
		for (String sku : skuInfoSplit) {
			if(skuMap.containsKey(sku)){
				skuMap.put(sku, skuMap.get(sku)+1);
			}else{
				skuMap.put(sku, 1);
			}
		}
		
		//排序
		List<Map.Entry<String, Integer>> mappingList = new ArrayList<Map.Entry<String, Integer>>(skuMap.entrySet());
		Collections.sort(mappingList,
				new Comparator<Map.Entry<String, Integer>>() {
					public int compare(
							Map.Entry<String, Integer> mapping1,
							Map.Entry<String, Integer> mapping2) {
						return mapping1.getKey().compareTo(mapping2.getKey());
					}
		});
		
		//生成字符串
		StringBuilder sb=new StringBuilder();
		for (Map.Entry<String, Integer> mapping : mappingList) {
			String key = mapping.getKey();
			
			if(sb.length()>0){
				sb.append(";");
			}
			sb.append(key).append(":").append(mapping.getValue());
		}
		
		String goodsInfo=sb.toString();
		
		//查找匹配订单
		List<WorkOrder> pkgList=this.loadOrderForPkg(warehouseCode,"intimePrint",goodsInfo);
		if(pkgList!=null && pkgList.size()>0){
			WorkOrder workOrder=pkgList.get(0);
			List<EdiOrderItem> orderItems = this.ediOrderItemDao.findByOrdeno(workOrder.getOrder().getOrdeno());
			workOrder.getOrder().setOrderItems(orderItems);
			return workOrder;
		}else{
			return null;
		}
		
	}
	
	/**
	 * 根据SKU查询待包装的订单_单件
	 * @param customerCode 商家编码
	 * @param sku sku
	 * @return
	 */
	@Transactional(readOnly = false)
	public WorkOrder loadOrderBySku_single(String warehouseCode, String sku) {
		String goodsInfo=sku+":1";
		//查找匹配订单
		List<WorkOrder> pkgList=this.loadOrderForPkg(warehouseCode,"intimePrint",goodsInfo);
		if(pkgList!=null && pkgList.size()>0){
			WorkOrder workOrder=pkgList.get(0);
			List<EdiOrderItem> orderItems = this.ediOrderItemDao.findByOrdeno(workOrder.getOrder().getOrdeno());
			workOrder.getOrder().setOrderItems(orderItems);
			
			workOrder.setPkgLock("pkging");
			this.workOrderDao.save(workOrder);
			
			return workOrder;
		}else{
			return null;
		}
	}
	
	
	/**
	 * 根据SKU查询待包装的订单_多件
	 * @param customerCode 商家编码
	 * @param skuInfo sku信息
	 * @return
	 */
	@Transactional(readOnly = false)
	public WorkOrder loadOrderBySku_multi(String warehouseCode, String skuInfo) {
		
		//将skuInfo转化成map
		Map<String, Integer> skuMap=new HashMap<String, Integer>();
		String[] skuInfoSplit=skuInfo.split(";");
		for (String sku : skuInfoSplit) {
			if(skuMap.containsKey(sku)){
				skuMap.put(sku, skuMap.get(sku)+1);
			}else{
				skuMap.put(sku, 1);
			}
		}
		
		//排序
		List<Map.Entry<String, Integer>> mappingList = new ArrayList<Map.Entry<String, Integer>>(skuMap.entrySet());
		Collections.sort(mappingList,
				new Comparator<Map.Entry<String, Integer>>() {
					public int compare(
							Map.Entry<String, Integer> mapping1,
							Map.Entry<String, Integer> mapping2) {
						return mapping1.getKey().compareTo(mapping2.getKey());
					}
		});
		
		//生成字符串
		StringBuilder sb=new StringBuilder();
		for (Map.Entry<String, Integer> mapping : mappingList) {
			String key = mapping.getKey();
			
			if(sb.length()>0){
				sb.append(";");
			}
			sb.append(key).append(":").append(mapping.getValue());
		}
		
		String goodsInfo=sb.toString();
		
		//查找匹配订单
		List<WorkOrder> pkgList=this.loadOrderForPkg(warehouseCode,"intimePrint",goodsInfo);
		if(pkgList!=null && pkgList.size()>0){
			WorkOrder workOrder=pkgList.get(0);
			List<EdiOrderItem> orderItems = this.ediOrderItemDao.findByOrdeno(workOrder.getOrder().getOrdeno());
			workOrder.getOrder().setOrderItems(orderItems);
			
			workOrder.setPkgLock("pkging");
			this.workOrderDao.save(workOrder);
			
			return workOrder;
		}else{
			return null;
		}
		
	}

	/**
	 * 核对商品和订单
	 * @param orderno
	 * @param skuInfo
	 * @return  success：验证成功    error： 验证失败
	 */
	public String checkGoodsInfo(String orderno, String skuInfo) {
		try {
			WorkOrder workOrder=this.workOrderDao.loadOrderByOrderno(orderno);
			
			if(workOrder==null){
				return "error";
			}
			
			//将skuInfo转化成map
			Map<String, Integer> skuMap=new HashMap<String, Integer>();
			String[] skuInfoSplit=skuInfo.split(";");
			for (String sku : skuInfoSplit) {
				if(skuMap.containsKey(sku)){
					skuMap.put(sku, skuMap.get(sku)+1);
				}else{
					skuMap.put(sku, 1);
				}
			}
			
			//排序
			List<Map.Entry<String, Integer>> mappingList = new ArrayList<Map.Entry<String, Integer>>(skuMap.entrySet());
			Collections.sort(mappingList,
					new Comparator<Map.Entry<String, Integer>>() {
						public int compare(
								Map.Entry<String, Integer> mapping1,
								Map.Entry<String, Integer> mapping2) {
							return mapping1.getKey().compareTo(mapping2.getKey());
						}
			});
			
			//生成字符串
			StringBuilder sb=new StringBuilder();
			for (Map.Entry<String, Integer> mapping : mappingList) {
				String key = mapping.getKey();
				
				if(sb.length()>0){
					sb.append(";");
				}
				sb.append(key).append(":").append(mapping.getValue());
			}
			
			String goodsInfo=sb.toString();
			
			//比较
			if(goodsInfo.equals(workOrder.getGoodsInfo())){
				return "success";
			}else{
				return "error";
		    }
		
		} catch (Exception e) {
			
			return "error";
		}
	}
	
	public WorkOrder loadByOrdernoOrCustomerorderno(String orderno){
		return this.workOrderDao.loadByOrdernoOrCustomerorderno(orderno);
	}
	
	public List<WorkOrder> loadByCustomerorderno(String orderno,String customerCode){
		return this.workOrderDao.loadByCustomerOrdeno(orderno,customerCode);
	}

	/**
	 * 取消订单
	 * @param orderno
	 * @param jobuuid
	 * @return
	 * @throws Exception 
	 */
	@Transactional(readOnly = false,rollbackFor=Exception.class)
	public String cancelOrder(String orderno, String jobuuid) throws Exception {
		return cancelOrder(orderno, jobuuid, true);
	}
	/**
	 * 取消订单
	 * @param orderno
	 * @param jobuuid
	 * @return
	 * @throws Exception 
	 */
	@Transactional(readOnly = false,rollbackFor=Exception.class)
	public String cancelOrder(String orderno, String jobuuid,boolean isSendQm) throws Exception {
		try {
			User user=this.userDao.findByJobuuid(jobuuid);
			
			Date now=new Date();
			EdiOrder ediOrder=this.ediOrderService.findByOrdeno(orderno);
			
			if(ediOrder==null){
				return "noexist"; //不存在
			}
			if((user.getCustomers()+":").indexOf(ediOrder.getCustomerCode()+":")==-1){
				return "noexist"; //不存在
			}
			
			if("cancel".equals(ediOrder.getOrderStatus())){
				return "cancel"; //已经取消
			}
			WorkOrder workOrder=this.workOrderDao.loadByOrderno(ediOrder.getOrdeno());
			
			if(workOrder==null){
				workOrder=new WorkOrder();
				workOrder.setCustomerCode(ediOrder.getCustomerCode());
				workOrder.setOrder(ediOrder);
				workOrder.setCustomerOrderno(ediOrder.getCustomerOrdeno());
				workOrder.setFromno(ediOrder.getFromno());
				workOrder.setCreateTime(new Date());
				workOrder.setStatus("0"); //未创建批次状态
				String goodsInfo=this.workBatchService.getGoodsInfo(ediOrder.getOrdeno());
				workOrder.setGoodsInfo(goodsInfo);
			}
			
			//如果是限制订单流入的商家，消除订单预定数量
			boolean mergeFlag = ediOrderService.ifMerge(ediOrder.getCustomerCode());
			if(mergeFlag){ //限制订单流入的商家
				//如果订单在创建了批次时取消，也应该消去预定的数量。
					if(!"finish".equals(ediOrder.getStatus()) || "1".equals(workOrder.getStatus())){
						//遍历订单，将订单的sku需求整理为：map<sku,num>格式 
					    Map<String, Integer> map=new HashMap<String, Integer>();
						EdiOrder order=workOrder.getOrder();
						List<EdiOrderItem> itemList=this.ediOrderItemDao.findByOrdeno(order.getOrdeno());
						for (EdiOrderItem item : itemList) {
							String sku=item.getSku();
							int qty=item.getQty();
							if(map.keySet().contains(sku)){
								map.put(sku, map.get(sku)+qty);
							}else{
								map.put(sku, qty);
							}
						}
						//消除订单预定数量 
						for(String sku: map.keySet()){
							int qty=map.get(sku);
							CusStockMerge merge=this.cusStockMergeDao.findCustomerWarSku(ediOrder.getCustomerCode(), ediOrder.getWarehouseCode(), sku);
							if(merge!=null){
								int _orderNum=merge.getOrderNum();
								int temp=_orderNum-qty;
								if (temp < 0) {
									log.error("预定库存异常，sku:"+sku+" ; 商家："+ediOrder.getCustomerCode()+" ; 仓库："+ediOrder.getWarehouseCode());
								}
								merge.setOrderNum(Math.max(temp,0));
								this.cusStockMergeDao.save(merge);
							}
						} 
				   }
			 }
			 
			
			//如果包装了，不能取消
			String status=workOrder.getStatus();
//			if(Integer.valueOf(status)>=6 && !"9".equals(status)){
//				return "sended"; //已经发货
//			}
			/**
			 * @张卫泽修改 由原来的已发货改成已包装
			 */
			if(Integer.valueOf(status)>=5 && !"9".equals(status)){
				return "package"; //已经包装
			}
			//当前任务都取消，修改库存占用
			if (("2".equals(workOrder.getStatus())) && (workOrder.getTaskCode() != null)) {
				List<WorkOrder> workorders = this.workOrderDao.findByTaskCode(workOrder.getTaskCode());
				boolean allCancel = true;
				for (WorkOrder order : workorders) {
					if ((order.getOrder().getOrdeno().equals(workOrder.getOrder().getOrdeno())) || ("cancel".equals(order.getCancelStatus())))
						continue;
					allCancel = false;
					break;
				}

				if (allCancel) {
					for (WorkOrder order : workorders) {
						String stockInfo = order.getStockInfo();
						String[] infoArray = stockInfo.split(";");

						for (String info : infoArray) {
							String[] _arr = info.split("_");
							String stockCode = _arr[0];
							String boxCode = _arr[1];
							String sku = _arr[2];
							Integer num = Integer.valueOf(_arr[3]);

							CusStock cusStock = cusStockDao.loadStock(order.getCustomerCode(), order.getWarehouseCode(), stockCode, boxCode, sku);
							cusStock.setSalesNum(Integer.valueOf(cusStock.getSalesNum().intValue() + num.intValue()));
							cusStock.setOrderNum(Integer.valueOf(cusStock.getOrderNum().intValue() - num.intValue()));
							cusStockDao.save(cusStock);
						}
					}
				}
			}
			try {
				if("ebill".equals(workOrder.getBillType())&&"YTO".equals(workOrder.getExpressCompany())&&(!"cancel".equals(ediOrder.getOrderStatus()))&&"create".equals(workOrder.getEbillStatus())){
//					SynchroShippedBatchQueue.putSendMessageQueue("cancelOrdenoYTO"+StatusEnums.split.getStatus()+workOrder.getOrder().getOrdeno()+"_"+workOrder.getWarehouseCode());//向圆通平台创建电子面单
				}
				if("ebill".equals(workOrder.getBillType())&&!StringUtils.isBlank(workOrder.getEbillNo())&&"YUNDA".equals(workOrder.getExpressCompany())&&!"cancel".equals(ediOrder.getOrderStatus())){
//					SynchroShippedBatchQueue.putSendMessageQueue("cancelOrdenoYUNDA"+StatusEnums.split.getStatus()+workOrder.getOrder().getOrdeno()+"_"+workOrder.getEbillNo()+"_"+workOrder.getWarehouseCode());
				}
                if("ebill".equals(workOrder.getBillType())&&!StringUtils.isBlank(workOrder.getEbillNo())&&"ZTO".equals(workOrder.getExpressCompany())&&!"cancel".equals(ediOrder.getOrderStatus())){
//                    ExpressConfigure expressConfigure = expressConfigureDao.findByWarehouseAndCompany(workOrder.getWarehouseCode(), "ZTO");
//                    final String partner = expressConfigure.getAccount();
//                    final String pwd = expressConfigure.getPassword();
//                    SynchroShippedBatchQueue.putSendMessageQueue("cancelOrdenoZTO"+StatusEnums.split.getStatus()+workOrder.getOrder().getOrdeno()+"_"+workOrder.getEbillNo()+"_"+workOrder.getWarehouseCode()+"_" +partner +"_" +pwd);
                }
                if("ebill".equals(workOrder.getBillType())&&!StringUtils.isBlank(workOrder.getEbillNo())&&"HTKY".equals(workOrder.getExpressCompany())&&!"cancel".equals(ediOrder.getOrderStatus())){
//                	ExpressConfigure expressConfigure = expressConfigureDao.findByWarehouseAndCompany(workOrder.getWarehouseCode(), "HTKY");
//                	MailBSHTUtil.BillPrintDeliveryCancel(workOrder.getEbillNo(), expressConfigure);
//                	SynchroShippedBatchQueue.putSendMessageQueue("cancelOrdenoHTKY"+StatusEnums.split.getStatus()+workOrder.getOrder().getOrdeno()+"_"+workOrder.getEbillNo()+"_"+workOrder.getWarehouseCode());
                }
			} catch (Exception e) {
				
			}
			
			//设置订单状态:取消
			ediOrder.setOrderStatus("cancel");
			ediOrder.setCheckRepeat(null);
			this.ediOrderService.save(ediOrder);
			
			//设置作业单状态:取消
			workOrder.setCancelStatus("cancel");
			if(workOrder.getExpressNo() != null)
				workOrder.setExpressNo(workOrder.getExpressNo() + "_");
			if(workOrder.getEbillNo() != null)
				workOrder.setEbillNo(workOrder.getEbillNo() + "_");
			workOrder.setWarehouseCode(ediOrder.getWarehouseCode());
			this.workOrderDao.save(workOrder);
			
			//创建取消单登记信息
			ExceptionOrder eOrder=new ExceptionOrder();
			eOrder.setExceptionType("cancel");
			eOrder.setRecallFlag("unrecall");
			eOrder.setCreaterUuid(jobuuid);
			eOrder.setCreateTime(now); 
			eOrder.setOrderno(ediOrder.getOrdeno());
			eOrder.setCustomerCode(ediOrder.getCustomerCode());
			eOrder.setWarehouseCode(ediOrder.getWarehouseCode());
			eOrder.setCancelStatus("regist");
			eOrder.setExpressNo(
					(StringUtils.isBlank(workOrder.getEbillNo())?"":workOrder.getEbillNo())
					+(StringUtils.isBlank(workOrder.getExpressNo())?"":workOrder.getExpressNo()));
			eOrder.setCustomerOrderno(ediOrder.getCustomerOrdeno());
			eOrder.setFromOrderno(ediOrder.getFromno());
			if(workOrder!=null){
				eOrder.setWarehouseCode(workOrder.getWarehouseCode());
			}
			this.exceptionOrderDao.save(eOrder);
			//取消菜鸟的电子面单
			if(StatusEnums.WAYBILL_TYPE_EBILL.getStatus().equals(workOrder.getBillType())  
					&& !StringUtils.isBlank(workOrder.getEbillNo())
					&& WmsContants.OPEN_CAINIAO.equals("1")){
				ShopSource shopSource =  shopSourceDao.findByShopCode(WmsContants.SHOP_CODE_CN); 
				WlbWaybillICancelResponse cancelResponse = TopClientUtils.cancelWaybillNo(ediOrder, shopSource);
				if (!StringUtils.isBlank(cancelResponse.getErrorCode())) {
					log.error("TopClientUtils.cancelWaybillNo case some error");
					log.error(cancelResponse.getErrorCode());
					log.error(cancelResponse.getMsg());
					log.error(cancelResponse.getSubCode());
					log.error(cancelResponse.getSubMsg());
					throw new RuntimeException(cancelResponse.getMsg());
				}
			}
			//日志
			OrderLog log=new OrderLog(
					ediOrder.getOrdeno(),
					ediOrder.getCustomerCode(),
					"10", //操作类型 （1.创建批次 2.创建任务  3.拣货完成 4.包装完成 5.发货完成 6.签收完成 7.异常登记 8.完成灯光拣选任务 9.打印单据 10.取消单 11.取消单重发）
					user,
					now,
					null,
					user.getRealname()+"取消订单");
			this.orderLogDao.save(log);
			
			if(isSendQm){
				try{
					this.log.info("------调用奇门出库单流水 (取消) orderno："+orderno+"---start------");
					Map<String,Object> params = new HashMap<String,Object>();
					params.put("ediOrder", ediOrder);
					params.put("status", "cancel");
					
					deliveryProcessService.send(params,ediOrder.getCustomerCode());
					this.log.info("------调用奇门出库单流水 (取消) orderno："+orderno+"---end------");
				}catch(Exception e){
					e.printStackTrace();
				}
			}
			if(!("0".equals(workOrder.getStatus()) || "1".equals(workOrder.getStatus()))){
				finishWorkTask(workOrder, now);
				finishWorkBatch(workOrder, now);
			}
			return "success";
		
		} catch (Exception e) {
			log.error("cancelOrder",e);
			throw e;
		}
		
	}
	
	/**
	 * 保存
	 * @param workOrder
	 */
	@Transactional(readOnly = false)
	public void save(WorkOrder workOrder) {
		this.workOrderDao.save(workOrder);
	}
	/**
	 * 设置属性明细
	 * @param workOrder 
	 */
	private void setDetailCache(WorkOrderNoCascade workOrder){
		
		//customer
		String customerCode=workOrder.getCustomerCode();
		Customers customer = null;
			customer=this.customersDao.findByCustomerCode(customerCode);
		workOrder.setCustomer(customer);
		
		//warehouse
		String warehouseCode=workOrder.getWarehouseCode();
		AreaGroup warehouse = null;
		warehouse=this.areaGroupDao.findByGroupCode(warehouseCode);
		workOrder.setWarehouse(warehouse);
		
		
		LogisticsCompany expressCmp = null;
		expressCmp=this.logisticsCompanyDao.findCompanyByCode(workOrder.getExpressCompany());
		
		//订单详情
//		List<EdiOrderItem> orderItems = this.ediOrderItemDao.findByOrdeno(workOrder.getOrder().getOrdeno());
//		workOrder.getOrder().setOrderItems(orderItems);
		
		//快递公司中文名
//		LogisticsCompany expressCmp=this.logisticsCompanyDao.findCompanyByCode(workOrder.getExpressCompany());
		if(expressCmp!=null){
			workOrder.setExpressChinaName(expressCmp.getCompanyName());
		}
	}
	/**
	 * 设置属性明细
	 * @param workOrder 
	 */
	private void setDetail(WorkOrder workOrder){
		//customer
		String customerCode=workOrder.getCustomerCode();
		Customers customer=this.customersDao.findByCustomerCode(customerCode);
		workOrder.setCustomer(customer);
		
		//warehouse
		String warehouseCode=workOrder.getWarehouseCode();
		AreaGroup warehouse=this.areaGroupDao.findByGroupCode(warehouseCode);
		workOrder.setWarehouse(warehouse);
		
		//订单详情
		List<EdiOrderItem> orderItems = this.ediOrderItemDao.findByOrdeno(workOrder.getOrder().getOrdeno());
		workOrder.getOrder().setOrderItems(orderItems);
		
		//快递公司中文名
		LogisticsCompany expressCmp=this.logisticsCompanyDao.findCompanyByCode(workOrder.getExpressCompany());
		if(expressCmp!=null){
			workOrder.setExpressChinaName(expressCmp.getCompanyName());
		}
	}

	/**
	 * 异常单重发
	 * @param orderno
	 * @param jobuuid
	 * @return
	 * @throws Exception 
	 */
	@Transactional(readOnly = false,rollbackFor=Exception.class)
	public String recallOrder(String orderno, String jobuuid) throws Exception  {
		try {
			
			EdiOrder order=this.ediOrderService.findByOrdeno(orderno);
			if(order==null){
				return "noExist"; //不存在此单号
			}
			
			ExceptionOrder eOrder=this.exceptionOrderDao.loadByOrderno(orderno);
			if( "recall".equals(eOrder.getRecallFlag()) ){
				return "recalled"; //已经重发了，不能重复重发
			}
			
			//修改ExceptionOrder状态
			eOrder.setRecallFlag("recall");
			this.exceptionOrderDao.save(eOrder);
			
			//修改原订单状态
			User user=this.userDao.findByJobuuid(jobuuid);
			order.setOrderStatus("recall");
			this.ediOrderService.save(order);
			
			//订单日志
			String orderno_new=orderno+"R";
			OrderLog orderlog=new OrderLog(orderno,
					order.getCustomerCode(), 
					"11", //操作类型 （1.创建批次 2.创建任务 3.拣货完成 4.包装完成 5.发货完成 6.签收完成 7.异常登记 8.完成灯光拣选任务 9.打印单据 10.取消单 11.异常单重发 12.取消单拦截标识 13.创建退回单 14.退回单收货 15.退回单质检 16.退回单入库）
					user,
					new Date(),
					null, 
					user.getRealname()+"异常单重发,新的订单号("+orderno_new+")");
			this.orderLogDao.save(orderlog);
			
			//创建新订单信息
			EdiOrder order_new=(EdiOrder) order.clone();
			order_new.setId(null);
			order_new.setOrderStatus("ok");
			order_new.setStatus("pending");
			order_new.setOrdeno(orderno_new);
			this.ediOrderService.save(order_new);
			
			List<EdiOrderItem> itemList=this.ediOrderItemDao.findByOrdeno(orderno);
			List<EdiOrderItem> itemList_new=new ArrayList<EdiOrderItem>();
			for (EdiOrderItem item : itemList) {
				EdiOrderItem item_new=(EdiOrderItem) item.clone();
				item_new.setId(null);
				item_new.setOrdeno(orderno_new);
				itemList_new.add(item_new);
			}
			this.ediOrderItemDao.save(itemList_new);
			
			//订单日志
			OrderLog orderlog_new=new OrderLog(orderno_new,
					order_new.getCustomerCode(), 
					"11", //操作类型 （1.创建批次 2.创建任务 3.拣货完成 4.包装完成 5.发货完成 6.签收完成 7.异常登记 8.完成灯光拣选任务 9.打印单据 10.取消单 11.异常单重发 12.取消单拦截标识 13.创建退回单 14.退回单收货 15.退回单质检 16.退回单入库）
					user,
					new Date(),
					null, 
					user.getRealname()+"创建重发订单,原始订单号("+orderno+")");
			this.orderLogDao.save(orderlog_new);
			
			
			return "success";
		} catch (Exception e) {
			
			throw e;
		}
	}

	/**
	 * 根据订单号或者快递单号查询
	 * @param no
	 * @return
	 */
	public WorkOrder loadByOrdernoOrExpressno(String no) {
		return this.workOrderDao.loadByOrdernoOrExpressno(no);
	}

	public WorkOrder loadByAnyOrderno(String orderno) {
		return this.workOrderDao.loadByAnyOrderno(orderno);
	}

	/**
	 * 分页查询
	 * @param param
	 * @param curPage
	 * @param length
	 * @return
	 */
	public Page<WorkOrder> loadPageOrder(Map<String, Object> param,int curPage, int pageSize) {
	    PageRequest pageRequest = new PageRequest(curPage-1, pageSize);
	    Specification<WorkOrder> spec = getWhereClause(param);
	    Page<WorkOrder> page = this.workOrderDao.findAll(spec, pageRequest);
	    return page;
	}
	
	public Page<WorkOrder> findByJson(QueryParamHolder param) {
		return findByJson(param, workOrderDao, WorkOrder.class);
	}
	
	@Transactional(readOnly = false)
	public List<WorkOrder> findByTaskCodes(String taskCode){
		WorkGuaranteeTask task = workGuaranteeTaskDao.findByTaskCode(taskCode);
		List<WorkOrder> workOrder = workOrderDao.findByGuaranteeTaskCode(taskCode,task.getBatchCode());
		List<WorkOrder> workOrders = new ArrayList<WorkOrder>();
		
		for(WorkOrder order : workOrder){
			EdiOrder ediOrder = ediOrderService.findByOrderNoDetail(order.getOrder().getOrdeno());
			List<EdiOrderItem> ediOrderItem = new ArrayList<EdiOrderItem>();
			if(task.getShopCode().equals(ediOrder.getShopCode())){
				for(EdiOrderItem item : ediOrder.getOrderItems()){
					if("1".equals(item.getSellFlg())){
						ediOrderItem.add(item);
					}
				}
				order.getOrder().setOrderItems(null);
				order.getOrder().setOrderItems(ediOrderItem);
				workOrders.add(order);
				workOrderDao.updateGuaranteeStatusByOrder("1",order.getId());
			}
		}
		return workOrders;
	}
	
	@Transactional(readOnly = false)
	public List<WorkOrder> findByordenos(String ordenos){
		List<WorkOrder> workOrders = new ArrayList<WorkOrder>();
		String[] lists=ordenos.split(":");
		WorkOrder wo = workOrderDao.loadByOrderno(lists[0]);
		WorkGuaranteeTask task = workGuaranteeTaskDao.findByTaskCode(wo.getGuaranteeCode());
		for(String o:lists){
			EdiOrder ediOrder = ediOrderService.findByOrderNoDetail(o);
			WorkOrder workOrder = workOrderDao.findByOrder(ediOrder.getOrdeno());
			List<EdiOrderItem> ediOrderItem = new ArrayList<EdiOrderItem>();
			if(task.getShopCode().equals(ediOrder.getShopCode())){
				for(EdiOrderItem item : ediOrder.getOrderItems()){
					if("1".equals(item.getSellFlg())){
						ediOrderItem.add(item);
					}
				}
				workOrder.getOrder().setOrderItems(null);
				workOrder.getOrder().setOrderItems(ediOrderItem);
				workOrders.add(workOrder);
				workOrderDao.updateGuaranteeStatusByOrder("1",workOrder.getId());
			}
		}
		return workOrders;
	}
	

	public WorkOrder findOne(long id){
		return workOrderDao.findOne(id);
	}
	
	
	/**
	 * 根据来源单号查找订单号
	 * @param fromno
	 * @return
	 */
	public List<WorkOrder> findByFromno(String fromno){
		List<WorkOrder> wos = workOrderDao.findFromno(fromno);
		return wos;
	}
	
	public List<WorkOrderInfoVo> findPickDetail(String taskCode){
		List<WorkOrder> orderList = workOrderDao.findByTaskCode(taskCode);
		LinkedHashMap<String, StringBuffer> map = new LinkedHashMap<String, StringBuffer>();
		List<WorkOrderInfoVo> voList = new ArrayList<WorkOrderInfoVo>();
		for(WorkOrder wo : orderList){
			String goodsInfo = wo.getGoodsInfo();
			StringBuffer taskCodeRankNo = new StringBuffer();
			taskCodeRankNo.append(wo.getTaskCode()).append("-").append(wo.getRankno());
			if(map.containsKey(goodsInfo)){
				map.put(goodsInfo, map.get(goodsInfo).append(taskCodeRankNo).append("；"));
			}else{
				map.put(goodsInfo, taskCodeRankNo.append("；"));
			}
		}
		for(Map.Entry<String,StringBuffer> m : map.entrySet()){
			String goodsInfo = m.getKey();
			StringBuffer taskCodes = m.getValue();
			String [] goods = goodsInfo.split(";");
			List<WorkOrderInfoItemVo> itemVos = new ArrayList<WorkOrderInfoItemVo>();
			for(String good : goods){
				String [] g = good.split(":");
				EdiGoodsSku egs = ediGoodsSkuDao.findByCustomerCodeAndSku("MID", g[0]);
				WorkOrderInfoItemVo itemVo = new WorkOrderInfoItemVo();
				itemVo.setGoodName(egs.getSkuName());
				itemVo.setSkuAndqty(good);
				itemVos.add(itemVo);
			}
			WorkOrderInfoVo vo = new WorkOrderInfoVo();
			vo.setVoItem(itemVos);
			vo.setTaskCode(taskCodes.toString());
			voList.add(vo);
		}
		return voList;
	}

	public List<WorkOrder> findByExpressNo(String expressNo) {
		return workOrderDao.findByExpressNo(expressNo);
	}
	
	public WorkOrder findByTaskAndOrder(String taskCode,String expressNo){
		return workOrderDao.loadByTaskAndExpress(taskCode, expressNo);
	}
	
	/**
	 * 订单复核
	 * 根据订单号和运单号查询数据
	 * @param orderNo
	 * @param expressNo
	 * @return [参数说明]
	 * 
	 * @return List<WorkOrder> [返回类型说明]
	 * @exception throws [违例类型] [违例说明]
	 * @see [类、类#方法、类#成员]
	 * @author zhangpeijun
	 */
	public List<WorkOrder> reCheckOrderNoAndExpressNO(String orderNo,String expressNo){
	    return workOrderDao.reCheckOrderNoAndExpressNO(orderNo, expressNo);
	}
	
	/**
	 * 根据任务号修改随箱单打印次数
	 * @param taskCodes 订单的taskCode组合
	 */
	@Transactional(readOnly = false,rollbackFor=Exception.class)
	public void updatePrintFormFlagByTaskCodes(List<String> taskCodes){
		workOrderDao.updatePrintFormFlagByTaskCodes(taskCodes);
	}
	
	/**
	 * 修改随箱单打印次数
	 * @param taskCode 订单的taskCode
	 */
	@Transactional(readOnly = false,rollbackFor=Exception.class)
	public void updatePrintFormFlagByTaskCode(String taskCode){
		workOrderDao.updatePrintFormFlagByTaskCode(taskCode);
	}
	
	/**
	 * 根据订单号修改随箱单打印次数
	 * @param Orders 订单号
	 * @return
	 */
	@Transactional(readOnly = false,rollbackFor=Exception.class)
	public int updatePrintFormFlagByOrders(String Orders){
		String sql="update work_order set print_form_flag=print_form_flag+1 where orderno in "+Orders+"";
		return jdbcTemplate.update(sql);
	}
	/**
	 * 根据运单号好仓库编码获取作业订单
	 * @param logistic 运单号
	 * @param warehouseCode 仓库编码
	 * @return
	 */
	public WorkOrder loadByExpressNoAndWarehouseCode(String logistic,
			String warehouseCode) {
		return workOrderDao.loadByExpressNoAndWarehouseCode(logistic,warehouseCode);
	}
	
	
	/**
	 * @param 
	 * @return 
	 * @throws 
	 * @author <a href=mailto:libin@nryuncang.com>libin</a>
	 * @version 1.0.0
	 */
	public String getWhereParam(WorkOrder w) {
        StringBuffer tmp = new StringBuffer();
        if (StringUtils.isNotBlank(w.getCustomerCode())) {
            tmp.append(" and a.customer_code = '" + w.getCustomerCode() + "'");
        }
        if (StringUtils.isNotBlank(w.getWarehouseCode())) {
            tmp.append(" and a.warehouse_code = '" + w.getWarehouseCode() + "'");
        }
        if (StringUtils.isNotBlank(w.getExpressCompany())) {
            tmp.append(" and b.cacode ='" + w.getExpressCompany() + "'");
        }
        return tmp.toString();
    }
	
	/**
	 * 将外部资料同步到系统数据库中
	 * @param workOrders 修改的对象集合
	 * @return 成功的个数
	 * @throws 
	 * @author <a href=mailto:libin@nryuncang.com>libin</a>
	 * @version 1.0.0
	 */
	@Transactional(rollbackFor=Exception.class,readOnly = false)
    public int saveWorkOrderFromInput(List<WorkOrder> workOrders) {
	    int count = 0;
        String [] sql=new String[workOrders.size()];
        for (int i = 0; i < workOrders.size(); i++) {
            WorkOrder w = workOrders.get(i);
            
            sql[i]="update work_order a,edi_order b set a.ebill_no =CONCAT(case a.cancel_status when 'cancel' then '_' else '' end,'" + w.getExpressNo() + "')"
                 + " , a.express_built_type = '1', a.input_time = '" + DateUtils.getCurrentDateHHMM() + "',express_company='" + w.getExpressCompany() + "' "
                 + " where (a.ebill_no = '' or a.ebill_no is null) and a.orderno = '" + w.getOrderNo() + "' and (a.print_status <> 'printed' or a.print_status is null) "
                 + " and a.orderno=b.ordeno "
                 + " and not exists (select * from (select id from work_order where ebill_no = '" + w.getExpressNo() + "' or express_no = '" + w.getExpressNo() + "') o)"
                 + getWhereParam(w) ;
        }
        log.info("saveWorkOrderFromInput--save--sql:"+sql[0]);
        int [] n= jdbcTemplate.batchUpdate(sql);
        for (int i : n) {
            if (i == 1) {
                count ++;
            }
        }
        return count;
    }
	
	/**
	 * 统计导入失败的订单
	 * @param 
	 * @return 失败原因
	 * @throws 
	 * @author <a href=mailto:libin@nryuncang.com>libin</a>
	 * @version 1.0.0
	 */
	public Map<String, List<WorkOrder>>  getInputExceptionOrders(String orders,List<WorkOrder> workOrders) {
	    
	    Map<String, List<WorkOrder>> rMap= new HashMap<String, List<WorkOrder>>();
	    List<WorkOrder> wList =new ArrayList<WorkOrder>();//成功
	    List<WorkOrder> wList1 =new ArrayList<WorkOrder>();//失败
	    List<Map<String, Object>> rList =new ArrayList<Map<String,Object>>();
	    String myOrders=orders.substring(0, orders.length()-1);
	    
        String sql = "select a.orderno,case when a.ebill_no <> '' then CONCAT('该订单已存在运单号',a.ebill_no) "
                                      + " else case when a.print_status = 'printed' then '该订单已打印,打印状态已修改' "
                                      + "           else '运单号重复,系统中存在待导入的运单 或其他' end"
                                      + " end results,"
                                      + " c.customer_name,b.group_name,d.caname,a.express_built_type"
                     + " from work_order a LEFT JOIN pms_areagroup b ON b.group_code=a.warehouse_code "
                     + "                   LEFT JOIN customers c ON c.customer_code=a.customer_code "
                     + "                   LEFT JOIN edi_order d on d.ordeno = a.orderno "
                     + " where a.express_built_type <>'1' and a.orderno in (" + myOrders + ") ";//a.express_built_type <>'1' and
        rList = jdbcTemplate.queryForList(sql);
        for (Map<String, Object> map : rList) {
            WorkOrder tmpOrder = new WorkOrder();
            tmpOrder.setOrderNo((String)map.get("orderno"));
            tmpOrder.setGoodsInfo((String)map.get("results"));
            tmpOrder.setCustomerCode((String)map.get("customer_name"));//临时对象,用名称代替编码
            tmpOrder.setWarehouseCode((String)map.get("group_name"));
            tmpOrder.setExpressCompany((String)map.get("caname"));
            for (WorkOrder workOrder : workOrders) {
                if(workOrder.getOrderNo().equals(tmpOrder.getOrderNo())) {
                    tmpOrder.setEbillNo(workOrder.getExpressNo()); 
                    break;
                }
            }
            
            if ("1".equals((String)map.get("express_built_type"))) {
                wList.add(tmpOrder);
            } else {
                wList1.add(tmpOrder);
            }
        }
        
        rMap.put("success", wList);
        rMap.put("fail", wList1);
        return rMap;
            
    }
	
	/**
     * 把选择的单据标记为已打印,作业订单
     * @param ids 修改订单的id组合
     * @return 成功的个数
     * @throws 
     * @author <a href=mailto:libin@nryuncang.com>libin</a>
     * @version 1.0.0
     */
    @Transactional(rollbackFor=Exception.class,readOnly = false)
    public int markWorkOrderPrinted(String ids) {

        String sql = "update work_order set print_status = 'printed', print_flag = print_flag + 1,express_list = CONCAT(express_list,ebill_no)"
                     + "where id in ("+ ids +")";

        return jdbcTemplate.update(sql);
    }

    /**
     * 把选择的单据标记为已打印,作业任务
     * @param ids 修改订单的id组合
     * @return 成功的个数
     * @throws 
     * @author <a href=mailto:libin@nryuncang.com>libin</a>
     * @version 1.0.0
     */
    @Transactional(rollbackFor=Exception.class,readOnly = false)
    public int markWorkTaskPrinted(String ids) {

        String sql = "update work_task a,work_order b,customers c set a.express_status = 'yes',"
                        + " a.print_status=case c.pack_status when '1' then case a.packform_status when 'yes' then 'printed' else a.print_status end"
                        + "                                                                   else 'printed' end"
                        + " where a.task_code=b.task_code and a.customer_code=c.customer_code and b.id in (" + ids + ") and "
                        + " not exists (select id from work_order where task_code=a.task_code and print_status is null and cancel_status = 'ok')";

        return jdbcTemplate.update(sql);
    }
    
    /**
     * 增加打印日志
     * @param ids 修改订单的id组合
     * @param shiroUser 当前用户
     * @return 成功的个数
     * @throws 
     * @author <a href=mailto:libin@nryuncang.com>libin</a>
     * @version 1.0.0
     */
    @Transactional(rollbackFor=Exception.class,readOnly = false)
    public int addWorkOrderPrintLog(String ids,ShiroUser shiroUser) {

        String sql = "insert into work_log(batch_code,work_type,info,work_time,worker_id)"
                     + " (select a.batch_code,'11' as work_type,CONCAT('执行标记已打印快递的单据:',a.task_code) as info,'" + DateUtils.formatDate(new Date()) + "' as work_time,"
                         + shiroUser.id + " as worker_id  from work_task a,work_order b where a.task_code=b.task_code and b.id in (" + ids + ") and "
                         + " not exists (select id from work_order where task_code=a.task_code and print_status is null and cancel_status = 'ok') "
                         + " group by batch_code,work_type,info,work_time,worker_id)";
                        

        return jdbcTemplate.update(sql);
    }
}